package com.koicarp.university.graduate.service.service.graduateInfoManage.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.koicarp.university.graduate.service.dao.*;
import com.koicarp.university.graduate.service.dto.bigView.GraduateSumDto;
import com.koicarp.university.graduate.service.dto.wx.GraduateInfoDto;
import com.koicarp.university.graduate.service.entity.LoginSessionWx;
import com.koicarp.university.graduate.service.entity.graduateInfoManage.GraduateInfo;
import com.koicarp.university.graduate.service.entity.graduateInfoManage.GraduateStatus;
import com.koicarp.university.graduate.service.entity.schoolInfoManage.Academy;
import com.koicarp.university.graduate.service.entity.schoolInfoManage.ClassManage;
import com.koicarp.university.graduate.service.entity.schoolInfoManage.Speciality;
import com.koicarp.university.graduate.service.service.graduateInfoManage.IGraduateInfoService;
import com.koicarp.university.graduate.service.service.wx.ILoginSessionWxService;
import com.koicarp.university.graduate.service.vo.graduateInfoManage.DeleteMoreDto;
import com.koicarp.university.graduate.service.vo.graduateInfoManage.GraduateInfoVo;
import com.koicarp.university.graduate.service.vo.graduateInfoManage.InfoStatusVo;
import com.koicarp.university.graduate.service.vo.wx.AuthIdentityVo;
import com.koicarp.university.graudate.common.constant.BaseConstant;
import com.koicarp.university.graudate.common.utils.DownLoadUtil;
import com.koicarp.university.graudate.common.utils.UniversityResponse;
import com.koicarp.university.graudate.common.utils.UniversityUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 【毕业生管理：毕业生信息表】(GraduateInfo)表服务实现类
 *
 * @author liutao
 * @since 2020-07-30 17:23:19
 */
@Service("graduateInfoService")
@Slf4j
@RequiredArgsConstructor
public class GraduateInfoServiceImpl extends ServiceImpl<GraduateInfoDao,GraduateInfo> implements IGraduateInfoService {

    private final GraduateInfoDao graduateInfoDao;

    private final AcademyDao academyDao;

    private final SpecialityDao specialityDao;

    private final ClassManageDao classManageDao;

    private final GraduateStatusDao graduateStatusDao;

    private final LoginSessionWxDao loginSessionWxDao;
    private String[] headers = new String[]{"毕业届	","学号","性别","姓名","学院","专业"	,"班级"	,"政治面貌","学历","手机号码","电子邮箱","是否就业","是否升学","是否为学生干部","全国大学生英语等级","计算机等级","奖学金次数"};
    @Override
    public void downloadTemplate(HttpServletResponse http) throws Exception {
        ClassPathResource classPathResource = new ClassPathResource("毕业生信息模板.xlsx");
        InputStream inputStream =classPathResource.getInputStream();
        List<Academy> academies = academyDao.queryAll(new Academy());
        List<Speciality> specialities = specialityDao.queryAll(new Speciality());
        List<ClassManage> classManages = classManageDao.queryAll(new ClassManage());
        Map<String,String> academyMap = new HashMap<>();
        Map<String,String> specialityMap = new HashMap<>();
        Map<String,String> classMap = new HashMap<>();
        for (Academy a:academies){
            academyMap.put(a.getAcademyName(),String.valueOf(a.getId()));
        }
        for (Speciality s:specialities){
            specialityMap.put(s.getSpecialityName(),String.valueOf(s.getId()));
        }
        for (ClassManage c:classManages){
            classMap.put(c.getClassName(),String.valueOf(c.getId()));
        }
        Map<Integer,String[]> dropDownMap  = new HashMap<>();
        dropDownMap.put(4,UniversityUtil.arrayClassCast(academyMap.keySet().toArray()));
        dropDownMap.put(5,UniversityUtil.arrayClassCast(specialityMap.keySet().toArray()));
        dropDownMap.put(6,UniversityUtil.arrayClassCast(classMap.keySet().toArray()));
        // 获取文件
        File file = classPathResource.getFile();
        String path = file.getPath();
        DownLoadUtil.writeDataToExcel(headers,null,path,0,1,dropDownMap);
        DownLoadUtil.downloadFile(path,http);
        file.delete();
    }

    @Override
    public UniversityResponse countDegreeGraduateSum() {
        UniversityResponse response = new UniversityResponse();
        response.code(BaseConstant.RESPONSE_CODE_SUCCESS_200);
        response.message(BaseConstant.RESPONSE_MESSAGE_OPR_SUCCESS);
        GraduateSumDto graduateSumDto = graduateInfoDao.countDegreeGraduateSum();
        response.data(graduateSumDto);
        return response;
    }

    @Override
    public UniversityResponse getGraduateInfoWithPage(GraduateInfoVo vo) {
        UniversityResponse response = new UniversityResponse();
        Page<GraduateInfo> page = null;
        boolean findOne = UniversityUtil.isNotNull(vo.getId());
        boolean isPage = UniversityUtil.isNotNull(vo.getPageNum())
                && UniversityUtil.isNotNull(vo.getPageSize());
        GraduateInfo graduateInfo=new GraduateInfo();
        BeanUtils.copyProperties(vo,graduateInfo);
        if (!findOne && !isPage){
            response.code(BaseConstant.RESPONSE_CODE_SUCCESS_200);
            response.message(BaseConstant.RESPONSE_MESSAGE_OPR_SUCCESS);
            Map listRes = new HashMap();
            listRes.put(BaseConstant.RESPONSE_RESULTSET,this.graduateInfoDao.queryAll(graduateInfo));
            response.data(listRes);
            return response;
        }
        if (findOne){
            page = new Page<>(1,1,false);
        } else{
            page = new Page<>(vo.getPageNum(),vo.getPageSize(),true);
        }
        IPage<GraduateInfo> result = null;

        result = this.graduateInfoDao.queryGraduateInfoWithPage(page, vo);

        if (findOne){
            List<GraduateInfo> list = result.getRecords();
            if (list == null || list.size() == 0){
                log.error("");
                response.code(BaseConstant.RESPONSE_CODE_FAILED_500);
                response.message(BaseConstant.RESPONSE_MESSAGE_OPR_RESULT_NULL);
            } else {
                response.code(BaseConstant.RESPONSE_CODE_SUCCESS_200);
                response.message(BaseConstant.RESPONSE_MESSAGE_OPR_SUCCESS);
                response.data(list.get(0));
            }
        } else {
            response.code(BaseConstant.RESPONSE_CODE_SUCCESS_200);
            response.message(BaseConstant.RESPONSE_MESSAGE_OPR_SUCCESS);
            Map<String, Object> dataTable = UniversityUtil.getDataTable(result);
            response.data(dataTable);
        }
        return response;
    }

    @Override
    @Transactional
    public UniversityResponse uploadGraduateInfo(List<InfoStatusVo> list) {
        UniversityResponse response = new UniversityResponse();
        response.code(BaseConstant.RESPONSE_CODE_SUCCESS_200);
        response.message(BaseConstant.RESPONSE_MESSAGE_OPR_SUCCESS);

        List<GraduateStatus> graduateStatusList = new ArrayList<>();
        List<GraduateInfo> graduateInfoList = new ArrayList<>();

        List<Academy> academies = academyDao.queryAll(new Academy());
        List<Speciality> specialities = specialityDao.queryAll(new Speciality());
        List<ClassManage> classManages = classManageDao.queryAll(new ClassManage());
        Map<String,Integer> academyMap = new HashMap<>();
        Map<String,Integer> specialityMap = new HashMap<>();
        Map<String,Integer> classMap = new HashMap<>();
        for (Academy a:academies){
            academyMap.put(a.getAcademyName(),a.getId());
        }
        for (Speciality s:specialities){
            specialityMap.put(s.getSpecialityName(),s.getId());
        }
        for (ClassManage c:classManages){
            classMap.put(c.getClassName(),c.getId());
        }

        for (InfoStatusVo i: list) {//将学院，专业，班级转换成id
            GraduateStatus status = new GraduateStatus();
            GraduateInfo graduateInfo = new GraduateInfo();
            BeanUtils.copyProperties(i,status);
            BeanUtils.copyProperties(i,graduateInfo);
            graduateInfo.setAcademyId(academyMap.get(i.getAcademyId()));
            graduateInfo.setSpecialityId(specialityMap.get(i.getSpecialityId()));
            graduateInfo.setClassId(classMap.get(i.getClassId()));
            graduateStatusList.add(status);
            graduateInfoList.add(graduateInfo);
        }
        graduateStatusDao.insertList(graduateStatusList);
        int flag = 0;
        for (GraduateInfo g: graduateInfoList) {
            g.setGraduateStatusId(graduateStatusList.get(flag).getId());
            flag++;
        }
        graduateInfoDao.insertList(graduateInfoList);

        return response;
    }

    @Override
    @Transactional
    public UniversityResponse authIdentity(AuthIdentityVo vo) {
        UniversityResponse response = new UniversityResponse();
        response.code(BaseConstant.RESPONSE_CODE_SUCCESS_200);
        response.message(BaseConstant.RESPONSE_MESSAGE_OPR_SUCCESS);
        List<GraduateInfoDto> list = graduateInfoDao.selectAuthIdentity(vo);
        if (list.size() > 0){
            LoginSessionWx loginSessionWx = new LoginSessionWx();
            loginSessionWx.setId(Integer.parseInt(vo.getLoginSessionId()));
            loginSessionWx.setGraduateId(list.get(0).getId());
            loginSessionWxDao.update(loginSessionWx);
            response.data(list.get(0));
            return response;
        }
        response.code(BaseConstant.RESPONSE_CODE_FAILED_500);
        response.message(BaseConstant.RESPONSE_MESSAGE_OPR_FAILED);
        return response;
    }

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public UniversityResponse getOneById(Integer id) {
        UniversityResponse response = new UniversityResponse();
        response.code(BaseConstant.RESPONSE_CODE_SUCCESS_200);
        response.message(BaseConstant.RESPONSE_MESSAGE_OPR_SUCCESS);
        GraduateInfoDto graduateInfoDto = this.graduateInfoDao.queryOneById(id);
        response.data(graduateInfoDto);
        return response;
    }

    @Override
    public GraduateInfo queryById(Integer id) {
        return this.graduateInfoDao.queryById(id);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<GraduateInfo> queryAllByLimit(int offset, int limit) {
        return this.graduateInfoDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param graduateInfo 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional
    public UniversityResponse insert(InfoStatusVo infoStatusVo) {
        UniversityResponse response = new UniversityResponse();
        response.code(BaseConstant.RESPONSE_CODE_SUCCESS_200);
        response.message(BaseConstant.RESPONSE_MESSAGE_OPR_SUCCESS);
        GraduateInfo graduateInfo = new GraduateInfo();
        GraduateStatus graduateStatus = new GraduateStatus();
        BeanUtils.copyProperties(infoStatusVo,graduateInfo);
        BeanUtils.copyProperties(infoStatusVo,graduateStatus);
        graduateStatusDao.insert(graduateStatus);
        graduateInfo.setGraduateStatusId(graduateStatus.getId());
        int i = this.graduateInfoDao.insert(graduateInfo);
        if ( i < 0 ){
            response.code(BaseConstant.RESPONSE_CODE_FAILED_500);
            response.message(BaseConstant.RESPONSE_MESSAGE_OPR_FAILED);
        }
        return response;
    }

    @Override
    public UniversityResponse insertExcel() {
        return null;
    }

    /**
     * 修改数据
     *
     * @param graduateInfo 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional
    public UniversityResponse update(InfoStatusVo infoStatusVo) {
        UniversityResponse response = new UniversityResponse();
        response.code(BaseConstant.RESPONSE_CODE_SUCCESS_200);
        response.message(BaseConstant.RESPONSE_MESSAGE_OPR_SUCCESS);
        GraduateInfo g = new GraduateInfo();
        GraduateStatus graduateStatus = new GraduateStatus();
        BeanUtils.copyProperties(infoStatusVo,g);
        BeanUtils.copyProperties(infoStatusVo,graduateStatus);
        g.setId(infoStatusVo.getGraduateInfoId());
        graduateStatus.setId(infoStatusVo.getGraduateStatusId());
        graduateInfoDao.update(g);
        int i = graduateStatusDao.update(graduateStatus);
        if ( i < 0){
            response.code(BaseConstant.RESPONSE_CODE_FAILED_500);
            response.message(BaseConstant.RESPONSE_MESSAGE_OPR_FAILED);
        }
        return response;
    }

    @Override
    public UniversityResponse updateGraduate(InfoStatusVo infoStatusVo) {
        UniversityResponse response = new UniversityResponse();
        response.code(BaseConstant.RESPONSE_CODE_SUCCESS_200);
        response.message(BaseConstant.RESPONSE_MESSAGE_OPR_SUCCESS);
        GraduateInfo g = new GraduateInfo();
        BeanUtils.copyProperties(infoStatusVo,g);
        int i = graduateInfoDao.update(g);
        if ( i < 0){
            response.code(BaseConstant.RESPONSE_CODE_FAILED_500);
            response.message(BaseConstant.RESPONSE_MESSAGE_OPR_FAILED);
        }
        return response;
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    @Transactional
    public UniversityResponse deleteByStudentId(InfoStatusVo infoStatusVo) {
        UniversityResponse response = new UniversityResponse();
        response.code(BaseConstant.RESPONSE_CODE_SUCCESS_200);
        response.message(BaseConstant.RESPONSE_MESSAGE_OPR_SUCCESS);
        this.graduateInfoDao.deleteByStudentId(infoStatusVo.getStudentId());
        int i = this.graduateStatusDao.deleteById(infoStatusVo.getGraduateStatusId());
        if ( i < 0 ){
            response.code(BaseConstant.RESPONSE_CODE_FAILED_500);
            response.message(BaseConstant.RESPONSE_MESSAGE_OPR_FAILED);
        }
        return response;
    }

    @Override
    @Transactional
    public UniversityResponse deleteListByStudentId(List<DeleteMoreDto> list) {
        UniversityResponse response = new UniversityResponse();
        response.code(BaseConstant.RESPONSE_CODE_SUCCESS_200);
        response.message(BaseConstant.RESPONSE_MESSAGE_OPR_SUCCESS);
        List<String>idList = new ArrayList<>();
        List<String>statusIdList = new ArrayList<>();
        for (DeleteMoreDto d: list) {
            idList.add(d.getId());
            statusIdList.add(d.getStatusId());
        }
        this.graduateInfoDao.deleteListByStudentId(idList);
        int i = this.graduateStatusDao.deleteListById(statusIdList);
        if ( i < 0 ){
            response.code(BaseConstant.RESPONSE_CODE_FAILED_500);
            response.message(BaseConstant.RESPONSE_MESSAGE_OPR_FAILED);
        }
        return response;
    }
}